#include <stdio.h>
#include <stdlib.h>

#include "header/FileSystem.h"
#include "header/CurrentStatus.h"
#include "util/Command.h"
#include "util/String.h"
#include "util/CreateFileParams.h"
#include "util/Printer.h"

int main() {
    setbuf(stdout,NULL);
    FileSystem *fs = FileSystem_init();
    CurrentStatus *currentStatus = CurrentStatus_init();
    char *buffer = (char *) calloc(MAX_INPUT_SIZE, sizeof(char));
    Command *command = NULL;
    while (True) {
        Print_currentDirectory(fs, currentStatus);
        fgets(buffer, MAX_INPUT_SIZE - 1, stdin);
        FREE_AND_SET_NULL(command)
        command = Command_create(buffer);
        CONTINUE_IF_TRUE(command == NULL, "Command is wrong")

        if (String_equal(command->commandStr, "createFile")) {
            CONTINUE_IF_TRUE(command->pSize < 2, "parameter wrong")
            CreateFileParams *params = CreateFileParams_init(command);
            CONTINUE_IF_TRUE(params == NULL, "parameter wrong")
            Print_CreateFileParams(params);
            CreateFileResult *result = FileSystem_createFile(fs, params, currentStatus);
            Status status = result->status;
            CreateFileParams_release(&params);
            FREE_AND_SET_NULL(result);
            CONTINUE_IF_TRUE(status == Error, "创建文件失败")
        } else if (String_equal(command->commandStr, "deleteFile")) {
            CONTINUE_IF_TRUE(command->pSize < 1, "parameter wrong")
            PathInfo *pathInfo = PathInfo_init(command->parameter[0]);
            Status status = FileSystem_deleteFile(fs, pathInfo, currentStatus);
            PathInfo_release(&pathInfo);
            CONTINUE_IF_TRUE(status == Error, "删除文件失败")
        } else if (String_equal(command->commandStr, "createDir")) {
            CONTINUE_IF_TRUE(command->pSize < 1, "parameter wrong")
            PathInfo *pathInfo = PathInfo_init(command->parameter[0]);
            Status status = FileSystem_createDir(fs, pathInfo, currentStatus);
            PathInfo_release(&pathInfo);
            CONTINUE_IF_TRUE(status == Error, "创建文件夹失败")
        } else if (String_equal(command->commandStr, "deleteDir")) {
            CONTINUE_IF_TRUE(command->pSize < 1, "parameter wrong")
            PathInfo *pathInfo = PathInfo_init(command->parameter[0]);
            Status status = FileSystem_deleteDir(fs, currentStatus, pathInfo);
            PathInfo_release(&pathInfo);
            CONTINUE_IF_TRUE(status == Error, "删除目录失败")
        } else if (String_equal(command->commandStr, "changeDir")) {
            CONTINUE_IF_TRUE(command->pSize < 1, "parameter wrong")
            PathInfo *pathInfo = PathInfo_init(command->parameter[0]);
            Status status = FileSystem_changeDir(fs, currentStatus, pathInfo);
            PathInfo_release(&pathInfo);
            CONTINUE_IF_TRUE(status == Error, "切换目录失败")
        } else if (String_equal(command->commandStr, "dir")) {
            FileSystem_dir(fs, currentStatus);
        } else if (String_equal(command->commandStr, "cp")) {
            CONTINUE_IF_TRUE(command->pSize < 2, "parameter wrong")
            PathInfo *srcPathInfo = PathInfo_init(command->parameter[0]);
            PathInfo *destPathInfo = PathInfo_init(command->parameter[1]);
            Status status = FileSystem_copyFile(fs, srcPathInfo, destPathInfo, currentStatus);
            PathInfo_release(&srcPathInfo);
            PathInfo_release(&destPathInfo);
            CONTINUE_IF_TRUE(status == Error, "复制文件失败")
        } else if (String_equal(command->commandStr, "sum")) {
            FileSystem_spaceUsage(fs);
        } else if (String_equal(command->commandStr, "cat")) {
            CONTINUE_IF_TRUE(command->pSize < 1, "parameter wrong")
            PathInfo *pathInfo = PathInfo_init(command->parameter[0]);
            Status status = FileSystem_cat(fs, pathInfo, currentStatus);
            PathInfo_release(&pathInfo);
            CONTINUE_IF_TRUE(status == Error, "找不到文件")
        } else if (String_equal(command->commandStr, "exit")) {
            FREE_AND_SET_NULL(command)
            break;
        } else if (String_equal(command->commandStr, "status")) {
            Print_FCBList(fs);
            Print_inodeList(fs);
            Print_bitmap(fs);
        } else {
            puts("Command is wrong");
        }
    }
    FREE_AND_SET_NULL(buffer)
    FileSystem_releaseAndPersist(&fs);
    FREE_AND_SET_NULL(currentStatus)
    puts("bye");
    return 0;
}
